﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Pigs.Enemies;
using Pigs.Weapons;

namespace pigs
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Prarie : Level
    {
        Texture2D fieldTex;
        Texture2D fieldTex2;

        PrairieBoss boss;
        Boolean bossPresent;
        Boolean bossDead;
        

        public Prarie(GameSettings set)
            : base(set)
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
            bossPresent = false;
            bossDead = false;
            levelName = "sk";
        }

        /// <summary>
        /// LoadContent images for gameplay
        /// </summary>
        public override void LoadContent()
        {
            wave = new Boolean[10];
            this.loadCommonContent();

            // Load collidable objects

            // Load Barn
            Texture2D barnTex = content.Load<Texture2D>("levels/Prairie/barn");
            Scenery barn = new Scenery(barnTex, new Vector2(viewport.Width - barnTex.Width, viewport.Height - (barnTex.Height - 15)));
            barn.initialize(-.4f, false);
            collidableBackground.Add(barn);

            // Load Tree
            //Texture2D treeTex = content.Load<Texture2D>("levels/Prairie/tree");
            //Scenery tree = new Scenery(treeTex, new Vector2(viewport.Width, viewport.Height - treeTex.Height));
            //tree.initialize(-.4f, false);
            //collidableBackground.Add(tree);

            // Load non-collidable objects
            fieldTex = content.Load<Texture2D>("levels/Prairie/fieldnotree");
            fieldTex2 = content.Load<Texture2D>("levels/Prairie/fieldnotreeflipped");
            Scenery field = new Scenery(fieldTex, new Vector2(0, 0));
            field.initialize(-0.1f, false);
            background.Add(field);

            field = new Scenery(fieldTex2, new Vector2(background.Last().rectangle.Right - 1, 0));
            field.initialize(-0.1f, false);
            background.Add(field);
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            this.commonUpdate(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            if (IsActive)
            {
                int WAVE_0 = 2000;
                int WAVE_1 = WAVE_0 + 3500;
                int WAVE_2 = WAVE_1 + 7000;
                int WAVE_3 = WAVE_2 + 11000; // + 33500
                int WAVE_4 = WAVE_3 + 48000; //int WAVE_4 = WAVE_3 + 96000;
                int WAVE_5 = WAVE_4 + 17000;
                int WAVE_6 = WAVE_5 + 25000;
                int WAVE_7 = WAVE_6 + 20000;
                int WAVE_8 = WAVE_7 + 35000;

                if (levelTime > WAVE_0 && !wave[0])
                {
                    for (int i = 1; i < 4; i++)
                    {
                        for (int j = 1; j < 4; j++) { addBasic(i * 100, j * 100); }
                    }

                    wave[0] = true;
                }

                if (levelTime > WAVE_1 && !wave[1])
                {
                    addNinja(50, 100);

                    for (int i = 1; i < 4; i++)
                    {
                        for (int j = 1; j < 4; j++) { addBasic(i * 100, j * 100); }
                    }

                    wave[1] = true;
                }

                if (levelTime > WAVE_2 && !wave[2])
                {
                    addSuicide(50, 400);
                    addSuicide(350, 400);

                    addNinja(550, 300);
                    addNinja(550, 500);

                    for (int i = 1; i < 4; i++)
                    {
                        for (int j = 1; j < 4; j++) { addBasic(i * 100, j * 100); }
                    }

                    wave[2] = true;
                }

                if (levelTime > WAVE_3 && !wave[3])
                {
                    addDrunk(50, 100);

                    addBasic(150, 50);
                    addBasic(150, 100);
                    addBasic(150, 150);

                    addBunny(250, 50);
                    addBunny(250, 150);

                    addBasic(350, 50);
                    addBasic(350, 100);
                    addBasic(350, 150);

                    addBasic(550, 50);
                    addBasic(550, 100);
                    addBasic(550, 150);

                    addBunny(750, 50);
                    addBunny(750, 150);

                    addSteel(950, 100);

                    // Load grain elevator
                    Texture2D elevatorTex = content.Load<Texture2D>("levels/Prairie/elevator");
                    Scenery elevator1 = new Scenery(elevatorTex, new Vector2(viewport.Width, viewport.Height - (elevatorTex.Height - 20)));
                    Scenery elevator2 = new Scenery(elevatorTex, new Vector2(elevator1.rectangle.X + elevatorTex.Width, viewport.Height - (elevatorTex.Height - 20)));

                    elevator1.initialize(-.4f, false);
                    elevator2.initialize(-.4f, false);

                    collidableBackground.Add(elevator1);
                    collidableBackground.Add(elevator2);

                    wave[3] = true;
                }

                if (levelTime > WAVE_4 && !wave[4])
                {
                    addNinja(50, 250);
                    //addNinja(50, 350);
                    //addNinja(50, 450);

                    //addDrunk(100, 150);
                    //addDrunk(100, 650);

                    addMagic(200, 350);

                    addLeader(600, 350);
                    //addBunny(600, 400);

                    for (int i = 1; i < 2; i++)
                    {
                        for (int j = 1; j < 2; j++) { addBasic(i * 100, j * 100); }
                    }

                    addSuicide(1000, 250);
                    //addSuicide(1000, 450);

                    for (int i = 15; i < 17; i++)
                    {
                        for (int j = 1; j < 2; j++) { addBasic(i * 100, j * 100); }
                    }

                    wave[4] = true;
                }

                if (levelTime > WAVE_5 && !wave[5])
                {
                    // Load duster
                    Texture2D dusterTex = content.Load<Texture2D>("levels/Prairie/duster");
                    Scenery duster1 = new Scenery(dusterTex, new Vector2(viewport.Width, 400));
                    Scenery duster2 = new Scenery(dusterTex, new Vector2(duster1.rectangle.X + dusterTex.Width / 2, 100));

                    duster1.initialize(-.4f, true);
                    duster2.initialize(-.4f, true);

                    collidableBackground.Add(duster1);
                    collidableBackground.Add(duster2);

                    addNinja(50, 50);
                    addNinja(50, 150);
                    addNinja(50, 250);

                    addBunny(50, 150);
                    addBunny(50, 275);

                    for (int i = 20; i < 26; i++)
                    {
                        for (int j = 1; j < 3; j++) { addBasic(i * 100, j * 100); }
                    }

                    addNinja(1000, 100);
                    addNinja(1000, 200);

                    wave[5] = true;
                }

                if (levelTime > WAVE_6 && !wave[6])
                {
                    // Load combine
                    Texture2D combineTex = content.Load<Texture2D>("levels/Prairie/straighthead");
                    Scenery combine = new Scenery(combineTex, new Vector2(viewport.Width, viewport.Height - (combineTex.Height - 20)));
                    combine.initialize(-.4f, false);
                    collidableBackground.Add(combine);

                    addBunny(300, 100);
                    addBunny(300, 150);
                    addBunny(300, 200);

                    for (int i = 1; i < 6; i++)
                    {
                        for (int j = 1; j < 6; j++) { addBasic(i * 100, j * 100); }
                    }

                    wave[6] = true;
                }

                if (levelTime > WAVE_7 && !wave[7])
                {
                    addLeader(100, 300);

                    addBunny(100, 200);

                    for (int i = 1; i < 6; i++)
                    {
                        for (int j = 1; j < 6; j++) { addBasic(i * 100, j * 100); }
                    }

                    addSuicide(100, 250);
                    addSuicide(100, 350);
                    addSuicide(100, 450);

                    addNinja(300, 300);
                    addNinja(300, 350);

                    for (int i = 20; i < 23; i++)
                    {
                        for (int j = 1; j < 3; j++) { addBasic(i * 100, j * 100); }
                    }

                    wave[7] = true;
                }

                //wave[7] = true;
                // Boss battle
                if (!wave[8] && levelTime > WAVE_8 && pigs.Count == 0) //wave[7] && 
                { //
                    // Rumble controller
                    foreach (Player p in players)
                    {
                        if (p.alive)
                        {
                            applyRumble(p, .2f, 0f, 5000);
                        }
                    }

                    addDrunk(100, 100);
                    addDrunk(100, 300);
                    addDrunk(300, 200);
                    addDrunk(300, 400);
                    addDrunk(600, 100);
                    addDrunk(600, 300);

                    Texture2D prairieBossTex = content.Load<Texture2D>("enemies/skboss");
                    boss = new PrairieBoss(prairieBossTex, new Vector2(viewport.Width - 100, 350), ScreenManager.GraphicsDevice, viewport.Width);
                    this.updateBackgrounds = false;
                    bossPresent = true;
                    
                    wave[8] = true;
                }

                if (bossPresent)
                {
                    boss.Update();
                    checkBossCollisions(gameTime);
                }

                if (bossDead && pigs.Count == 0) 
                {
                    doEndGame(true);
                }

                // Tile the background
                if (((int)background.Last().rectangle.Right) < (viewport.Width + 100))
                {
                    Scenery field = new Scenery(fieldTex, new Vector2(background.Last().rectangle.Right - 1, 0));
                    field.initialize(-0.1f, false);
                    background.Add(field);
                    field = new Scenery(fieldTex2, new Vector2(background.Last().rectangle.Right - 1, 0));
                    field.initialize(-0.1f, false);
                    background.Add(field);
                }
            }
        }

        /// <summary>
        /// check if the boss is colliding with the players
        /// the players bullets and other pigs
        /// </summary>
        void checkBossCollisions(GameTime gameTime)
        {
            
            foreach (Player p in players)
            {
                if (p.active)
                {
                    if (p.checkCollision(boss)) 
                    { 
                        p.health = -1;
                        p.notHit = false;
                        destroyPlayer(p, gameTime);
                    }

                    if (rand.Next(0, 40) == 1)
                    {
                        Corn c;
                        if (p.position.X < boss.position.X)
                        {
                            Vector2 start = new Vector2(boss.position.X, boss.position.Y + p.Height / 2);
                            c = new Corn(cornTexture, start);
                            c.Initialize(-1 * new Vector2(rand.Next(3, 6), rand.Next(10, 20)));
                        }
                        else
                        {
                            Vector2 start = new Vector2(boss.position.X, boss.position.Y + p.Height / 2);
                            c = new Corn(cornTexture, start);
                            c.Initialize(new Vector2(rand.Next(3, 6), rand.Next(10, 20)));
                        }
                        this.cornBullets.Add(c);
                    }
                }
                
                foreach (Bullet b in p.bullets)
                {
                    if (b.checkCollision(boss))
                    {
                        boss.health -= b.damage / (boss.defense  + settings.numberOfPlayers - 1);
                        b.active = false;
                        Explosion e = new Explosion(explosionTexture, b.center(), .3f);
                        explosions.Add(e);
                    }
                }

                foreach (Flame f in p.flames)
                {
                    if (f.checkCollision(boss)) { boss.health -= f.damage / (boss.defense + 2 + settings.numberOfPlayers); }
                }
            }
            foreach (Pig p in pigs)
            {
                if (p.checkCollision(boss))
                {
                    if (p.ID.Equals("drunk"))
                    {
                        p.active = false;
                        playSound(explosionSound);
                        Explosion e = new Explosion(explosionTexture, p.center(), 1);
                        explosions.Add(e);

                        if (boss.defenseIncrement % 2 == 0 && boss.defenseIncrement != boss.MAX_DEFENSE) { boss.defense++; }
                        else { boss.defenseIncrement++; }
                    }
                }
            }
            
            // add new pigs
            if (pigs.Count == 0 && wave[8])
            {
                addDrunk(100, rand.Next(100, 300));
                addDrunk(100, rand.Next(300, 500));
            }

            //check health of boss
            if (boss.health <= 0)
            {
                getLowestPlayer().score += 10000;
                bossDead = true;
                boss.active = false;
                bossPresent = false;
                playSound(explosionSound);
                Explosion e = new Explosion(explosionTexture, boss.center(), 3);
                explosions.Add(e);
            }
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            this.commonDraw(gameTime);
            if (bossPresent && !bossDead) { boss.Draw(spriteBatch); }
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
